import React, { Component } from 'react'
import { NavBar } from 'antd-mobile'
import styles from './index.module.scss'
import { getCity, getHotCity } from 'api/city'
import { getCityCurrent, setCityCurrent } from 'utils/storage'
import { List, AutoSizer } from 'react-virtualized'

const formatCityData = (list) => {
  const cityList = {}
  list.forEach((item) => {
    // 获取每个城市的首字母
    const first = item.short.substr(0, 1)
    // 判断 cityList中是否有这个分类
    if (cityList[first]) {
      cityList[first].push(item)
    } else {
      // 没有就创建
      cityList[first] = [item]
    }
  })
  const cityIndex = Object.keys(cityList).sort()
  return {
    cityList,
    cityIndex,
  }
}
const formatCityIndex = (letter) => {
  switch (letter) {
    case '#':
      return '当前定位'

    case 'hot':
      return '热门城市'

    default:
      return letter.toUpperCase()
  }
}
export default class IndexBarCom extends Component {
  async componentDidMount() {
    await this.loadCity()
    // 调用 measureAllRows 提前计算List 中每一行的高度 实现 scrollToRow的精确跳转
    // 调用这个方法 需要保证List中有数据
    this.cityListRef?.current?.measureAllRows()
  }

  state = {
    cityList: {},
    cityIndex: [],
    activeIndex: 0,
  }
  cityListRef = React.createRef()
  // 渲染每一行的函数
  rowRenderer = ({
    key, // key
    index, // 索引
    isScrolling, // 当前项是否在滚动中
    isVisible, // 当前项在List中是可见的
    style, // 给每一行数据添加样式
  }) => {
    const { cityIndex, cityList } = this.state
    const letter = cityIndex[index]
    return (
      <div key={key} style={style} className="city">
        <div className="title">{formatCityIndex(letter)}</div>
        {cityList[letter].map((item) => (
          <div
            className="name"
            key={item.value}
            onClick={() => this.clickListItem(item)}
          >
            {item.label}
          </div>
        ))}
      </div>
    )
  }
  // 动态计算每一行的高度
  getRowHeight = ({ index }) => {
    const { cityIndex, cityList } = this.state
    return 36 + cityList[cityIndex[index]].length * 50
  }
  // 索引列表项绑定点击事件
  // 在点击事件中 通过index 获取到当前索引号
  onClickCityIndex = (index) => {
    // 调用list组件的 scrollToRow 方法 让List组件滚动到指定行
    this.cityListRef.current.scrollToRow(index)
  }
  renderCityIndex() {
    const { cityIndex, activeIndex } = this.state

    return cityIndex.map((item, index) => (
      <li
        className="city_index_item"
        key={item}
        onClick={() => this.onClickCityIndex(index)}
      >
        <span className={activeIndex === index ? 'index_active' : ''}>
          {item === 'hot' ? '热' : item.toUpperCase()}
        </span>
      </li>
    ))
  }
  // 用于获取List组件中渲染行的信息
  onRowsRendered = ({ startIndex }) => {
    if (this.state.activeIndex !== startIndex) {
      this.setState({
        activeIndex: startIndex,
      })
    }
  }
  render() {
    const { cityIndex } = this.state
    return (
      <div style={{ height: window.innerHeight }} className={styles.indexBar}>
        <NavBar onBack={() => this.props.history.go(-1)}>城市列表</NavBar>
        <AutoSizer>
          {({ width, height }) => (
            <List
              ref={this.cityListRef}
              width={width}
              height={height}
              rowCount={cityIndex.length}
              rowHeight={this.getRowHeight}
              rowRenderer={this.rowRenderer}
              onRowsRendered={this.onRowsRendered}
              scrollToAlignment="start" // 保证被点击行 出现在页面顶部
            />
          )}
        </AutoSizer>

        <ul className="city_index">{this.renderCityIndex()}</ul>
      </div>
    )
  }
  loadCity = async () => {
    try {
      const { body: res } = await getCity({ level: 1 })
      const { body: hotRes } = await getHotCity()
      const { cityList, cityIndex } = formatCityData(res)

      cityList['hot'] = hotRes
      cityIndex.unshift('hot')
      cityList['#'] = [getCityCurrent()]
      cityIndex.unshift('#')
      this.setState({
        cityList,
        cityIndex,
      })
    } catch (err) {
      console.log(err)
    }
  }
  clickListItem = (item) => {
    setCityCurrent(item)
    this.props.history.push('/home')
  }
}
